
export class StringUtils {

    public static getShowUid(uid) {
        let result = uid + "";
        if (result.length >= 4) {
            result = "****" + result.substring(result.length - 4);
        }
        return result;
    }

    /** 把obj对象添加到url参数后面 */
    public static getHttpParamsUrl(url: string, params: any) {
        if (params) {
            let flag = 0;
            Object.keys(params).forEach((key) => {
                if (flag) {
                    url = `${url}&${key}=${params[key]}`
                } else {
                    url = `${url}?${key}=${params[key]}`
                }
                flag++;
            });
        }
        return encodeURI(url);
    }

    /** 获取str字节长度 */
    public static getCharLength(str) {
        var iLength = 0;  //记录字符的字节数
        for (var i = 0; i < str.length; i++) {//遍历字符串中的每个字符
            if (str.charCodeAt(i) > 255) {   //如果当前字符的编码大于255
                iLength += 2;    //所占字节数加2
            } else {
                iLength += 1;   //否则所占字节数加1
            }
        }

        return iLength;   //返回字符所占字节数
    }

    /** 剪切str 如果字数超过，则截取内容，拼接上“...”显示*/
    public static getSubStr(str, cutlength) {
        if (!str) {
            return str;
        }
        var newStr = str;
        if (str.length > cutlength) {
            newStr = str.substring(0, cutlength) + "...";
        }
        return newStr;
    }

    /**
     * 格式化输出时间
     * @param fmt 格式化参数
     * @param date 时间
     */
    public static dateFormat(fmt: string, date: Date) {
        let ret;
        const opt = {
            "Y+": date.getFullYear().toString(),        // 年
            "m+": (date.getMonth() + 1).toString(),     // 月
            "d+": date.getDate().toString(),            // 日
            "H+": date.getHours().toString(),           // 时
            "M+": date.getMinutes().toString(),         // 分
            "S+": date.getSeconds().toString()          // 秒
            // 有其他格式化字符需求可以继续添加，必须转化成字符串
        };
        for (let k in opt) {
            ret = new RegExp("(" + k + ")").exec(fmt);
            if (ret) {
                fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
            };
        };
        return fmt;
    }

    /**
     * 
     * @param dateString YYYY-mm-dd HH:MM:SS
     * @returns 
     */
    public static convertDateFromString(dateString) {
        if (!dateString) {
            return;
        }
        let date;
        if (dateString) {
            try {
                let arr1 = dateString.split(" ");
                let sdate = arr1[0].split('-');
                let stime = arr1[1].split(':');
                date = new Date(sdate[0], sdate[1] - 1, sdate[2], stime[0], stime[1], stime[2]);
            } catch (error) {

            }
            return date;
        }
    }

    /**
     * 
     * @param dateString YYYY-mm-dd
     * @returns 
     */
    public static convertDateFromString2(dateString) {
        if (!dateString) {
            return;
        }
        let date;
        if (dateString) {
            try {
                let sdate = dateString.split('-');
                date = new Date(sdate[0], sdate[1] - 1, sdate[2]);
            } catch (error) {

            }
            return date;
        }
    }
}

export class NumberUtils {
    /** 保留几位小数 */
    public static numKeepPotints(num: number, pointNum: number) {
        let numStr = num.toString();
        let result = numStr
        if (numStr.indexOf(".") != -1) {
            result = num.toFixed(pointNum);
        }
        return result;
    }

    /**
     * 
     * @param num 需要取整的值
     * @param prec 需要用0占位的数量 (1=10倍,2=100倍...)
     * @param ceil 是否向上取整
     */
    public static numFormatInt(num: number, prec: number, ceil: boolean = false) {
        let len = String(num).length;
        if (len <= prec) {
            return 0;
        }
        let mult = Math.pow(10, prec);
        return ceil ? Math.ceil(num / mult) * mult : Math.floor(num / mult) * mult;
    }

    /**转换成带逗号分割的字符串*/
    public static moneyToThousands(num: number | string) {
        if (typeof (num) == "string") {
            num = parseInt(num)
        }
        let result = '', counter = 0;
        num = (num || 0).toString();
        if (num.indexOf(".") != -1) {
            let numArray = num.split(".");
            num = numArray[0];
            result = "." + numArray[1];
        }
        for (let i = num.length - 1; i >= 0; i--) {
            counter++;
            result = num.charAt(i) + result;
            if (!(counter % 3) && i != 0) { result = ',' + result; }
        }
        return result;
    }

    public static toUnitNumber(num: number) {
        if (num >= 1000) {
            return num / 1000 + "K";
        }
        return num + "";
    }

    /**
     *
     * @param value 需要显示值
     * @param fractionDigits 保留的小数位数
     */
    public static toFloat(value, fractionDigits = 2, removeInvalidDigits = true) {
        try {
            // 如果含有科学记数显示,先转换成正常显示的字符串
            value = this.scientificToDecimal(value);
            //保留小数位
            let result = isNaN(value) ? value : this.setdigits(value, fractionDigits);
            //移除无效小数
            if (removeInvalidDigits) {
                return this.delete_zero(result);
            } else {
                return result;
            }

        } catch (e) {
            // 防止小数位数字越界
            return value * 1;
        }
    }

    /**
     * 
     * @param num 科学记数显示的数字或字符串
     */
    private static scientificToDecimal(num) {
        let data = String(num).split(/[eE]/);
        if (data.length == 1) return data[0];
        let z = '',
            sign = num < 0 ? '-' : '',
            str = data[0].replace('.', ''),
            mag = Number(data[1]) + 1;

        if (mag < 0) {
            z = sign + '0.';
            while (mag++) z += '0';
            return z + str.replace(/^\-/, '');
        }
        mag -= str.length;
        while (mag--) z += '0';
        return str + z;
    }

    /**
     * 保留指定的小数位数
     * @param value 初始值
     * @param fractionDigits 保留的位数
     */
    private static setdigits(value, fractionDigits) {
        let valueStr = value.toString();
        let arr = valueStr.split('.');
        //如果没有小数直接返回
        if (arr.length == 1) {
            //不需要保留小数
            if (!fractionDigits || fractionDigits == 0) {
                return valueStr;
            }
            //小数后面增补0占位
            valueStr = valueStr + "."
            for (let i = 0; i < fractionDigits; i++) {
                valueStr = valueStr + "0";
            }
            return valueStr;
        }
        //截断小数位数
        let decimalLen = arr[1].length;
        let disStr = arr[1].slice(0, fractionDigits);
        //如果数字的小数位数 < 需要保留的小数位数 小数后面增补0占位
        if (decimalLen < fractionDigits) {
            //需要增补的个数
            let len = fractionDigits - decimalLen;
            for (let i = 0; i < len; i++) {
                disStr = disStr + "0";
            }
        }
        //拼接整数+小数(数字)
        if (!isNaN(parseInt(disStr))) {
            disStr = '.' + disStr;
        }
        let newStr = arr[0] + disStr;
        return newStr;
    }

    //去掉无效的小数位0
    private static delete_zero(s: string): string {
        if (s.indexOf('.') > 0) {
            //去掉多余的0
            s = s.replace(new RegExp('0+?$'), '');
            //如最后一位是.则去掉
            s = s.replace(new RegExp('[.]$'), '');
        }
        return s;
    }
}

export class ObjUtils {
    //深度拷贝json对象的函数，
    //source：待拷贝对象
    //返回一个新的对象
    public static clone(source: Object): any {
        if (null == source || !source) {
            return source;
        }

        let newObject: any;
        let isArray = false;
        if ((source as any).length) {
            newObject = [];
            isArray = true;
        }
        else {
            newObject = {};
            isArray = false;
        }

        for (let key of Object.keys(source)) {
            if (null == source[key]) {
                if (isArray) {
                    newObject.push(null);
                }
                else {
                    newObject[key] = null;
                }
            }
            else {
                let sub = (typeof source[key] == 'object') ? this.clone(source[key]) : source[key];
                if (isArray) {
                    newObject.push(sub);
                }
                else {
                    newObject[key] = sub;
                }
            }
        }
        return newObject;
    }

    /**
     * 移除list一个元素返回新list
     * @param arr 原list
     * @param index 需要移除的元素索引
     */
    public static removeList(arr: any[], index: number) {
        let newarr: any[] = [];
        for (let i = 0; i < arr.length; i++) {
            if (i != index) {
                newarr.push(arr[i]);
            }
        }
        return newarr;
    }

}

export class RandomUtils {
    /**
     * 获取随机区间数 -num 到 num
     * @param num 
     */
    public static getRandomViNum(num: number): number {
        let vi = Math.round(Math.random()) == 0 ? -1 : 1;
        let viNum = Math.round(Math.random() * num);
        return (viNum * vi);
    }

    /**
     * 获取随机区间数 mini到maxi
     */
    public static random(mini, maxi) {
        return Math.round(Math.random() * (maxi - mini) + mini);
    }
}


const MONTHENGLISH = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
export class DateUtil {

    /**
     * 是否同一天
     * @param dateOne 
     * @param dateTwo 
     * @returns 
     */
    public static isSameDay(dateOne: Date, dateTwo: Date) {
        return !!dateOne && !!dateTwo
            && dateOne.getFullYear() == dateTwo.getFullYear()
            && dateOne.getMonth() == dateTwo.getMonth()
            && dateOne.getDate() == dateTwo.getDate();
    }
    /**
     * 两个时间相差天数
     * @param dateOne 
     * @param dateTwo 
     * @returns 
     */
    public static getDays(dateOne: Date, dateTwo: Date) {
        if (!dateOne || !dateTwo) {
            return 0;
        }
        dateOne.setHours(0);
        dateOne.setMinutes(0);
        dateOne.setSeconds(0);
        dateOne.setMilliseconds(0);

        dateTwo.setHours(0);
        dateTwo.setMinutes(0);
        dateTwo.setSeconds(0);
        dateTwo.setMilliseconds(0);

        return (dateOne.getTime() - dateTwo.getTime()) / (24 * 60 * 60 * 1000);
    }

    /**
     * 两个时间实际相差天数
     * @param dateOne 
     * @param dateTwo 
     * @returns 
     */
    public static getRealDays(dateOne: Date, dateTwo: Date) {
        if (!dateOne || !dateTwo) {
            return 0;
        }
        return (dateOne.getTime() - dateTwo.getTime()) / (24 * 60 * 60 * 1000);
    }

    /**
     * 几天前或者后的时间
     * @param definedTime
     * @param days
     */
    public static getDaysAfter(definedDate: Date, days: number): Date {
        // console.log("getDaysAfter old：" + days, StringUtils.dateFormat("YYYY-mm-dd HH:MM:SS", definedDate));
        let milliseconds = 1000 * 60 * 60 * 24 * days;//相隔时间
        let afterTime = definedDate.getTime() + milliseconds;
        let dateObj = new Date(afterTime);
        // console.log("getDaysAfter new：" + days, StringUtils.dateFormat("YYYY-mm-dd HH:MM:SS", dateObj));
        return dateObj;
    }

    /**
     * 秒 转 时间显示
     * @param timeNum 
     * @returns 
     */
    public static getDuration(timeNum: number) {
        let days = Math.floor(timeNum / 86400);
        let hours = Math.floor((timeNum % 86400) / 3600);
        let minutes = Math.floor(((timeNum % 86400) % 3600) / 60);
        let seconds = Math.floor(((timeNum % 86400) % 3600) % 60);
        // console.log("getDuration",  timeNum, days, hours, minutes, seconds);
        let duration = "";

        if (days > 0) {
            duration = duration + days + "d ";
        }
        if (hours < 10) {
            duration = duration + "0" + hours + ":";
        } else {
            duration = duration + hours + ":";
        }
        if (minutes < 10) {
            duration = duration + "0" + minutes + ":";
        } else {
            duration = duration + minutes + ":";
        }
        if (seconds < 10) {
            duration = duration + "0" + seconds;
        } else {
            duration = duration + seconds;
        }
        return duration;
    }

    /**
     * 当前周的开始和结束日期
     */
    public static getRangeWithCurrWeek() {

        let nowData = new Date();
        //获取今天的是周几
        let currentDay = nowData.getDay();
        //把currentDay == 0赋值给周日
        if (currentDay == 0) {
            currentDay = 7
        }
        // 获取周一的时间戳
        let monDayTime = nowData.getTime() - (currentDay - 1) * 24 * 60 * 60 * 1000;
        // 获取周日的时间戳
        let sunDayTime = nowData.getTime() + (7 - currentDay) * 24 * 60 * 60 * 1000;

        let monDate = new Date(monDayTime);
        let sunDate = new Date(sunDayTime);

        let weekstartday = MONTHENGLISH[monDate.getMonth()] + " " + monDate.getDate();
        let weekendday = MONTHENGLISH[sunDate.getMonth()] + " " + sunDate.getDate();

        // Apr 3 to 9
        return weekstartday + " to " + weekendday;

    }

    /**
     * 当前周剩余时间
     */
    public static getReaminTimeOfWeek() {

        let nowData = new Date();
        //获取今天的是周几
        let currentDay = nowData.getDay();
        //把currentDay == 0赋值给周日
        if (currentDay == 0) {
            currentDay = 7
        }

        let rhour = 23 - nowData.getHours();
        let rMinu = 59 - nowData.getMinutes();
        let rSec = 59 - nowData.getSeconds();

        let remainToday = rhour * 60 * 60 * 1000 + rMinu * 60 * 1000 + rSec * 1000;
        let remainAll = (7 - currentDay) * 24 * 60 * 60 * 1000 + remainToday;

        return remainAll;
    }

    /**
     * 根据时间戳获取日前和时间(时分秒)
     */
    public static getDateAndTime(time: number, format?: string) {
        if (!format) {
            format = "Y/m/d H:M:S"
        }
        let info = new Date(time);
        let timeFormat = StringUtils.dateFormat(format, info);
        return timeFormat;
    }

    /** 月份转为英文 
     * @param month 显示月份 1-12
     */
    public static getMonthChar(month: number | string) {
        if (typeof month == "number") {
            if (month >= 1 && month < 13)
                return MONTHENGLISH[month - 1];
            return month.toString();
        } else {
            let m = Number(month);
            if (m >= 1 && m < 13)
                return MONTHENGLISH[m - 1];
            return month;
        }
    }
}
